package interview.juc;

/**
 * @Author: zhangrongqing
 * @Date: 2019/11/28 16:09
 */
public class TestProducerAndConsumer {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Producer producer = new Producer(clerk);
        Consumer consumer = new Consumer(clerk);
        new Thread(producer, "生产者A").start();
        new Thread(producer, "生产者B").start();
        new Thread(consumer, "消费者A").start();
        new Thread(consumer, "消费者B").start();
    }
}

/**
 * 店员
 */
class Clerk {
    int product = 0;

    public synchronized void add() throws InterruptedException {
        System.out.println("店员进货");
        while (product >= 1) {                   //采用while循环，来防止虚假唤醒
            System.out.println("货源已满");
            this.wait();                        //解锁，然后提醒去消费
        }
        System.out.println(Thread.currentThread().getName() + "进货,货品剩余：" + ++product);
        this.notifyAll();                       //唤醒去消费
    }

    public synchronized void get() throws InterruptedException {
        System.out.println("店员售货");
        while (product <= 0) {
            System.out.println("货品售罄");
            this.wait();                        //解锁，提醒去进货
        }
        System.out.println("消费后货品剩余：" + --product);  //这边如果放在if-else里面会导致释放不了，导致死锁
        this.notifyAll();                      //唤醒进货
    }
}

class Producer implements Runnable {
    Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                clerk.add();
            } catch (InterruptedException e) {
            }
        }

    }
}

class Consumer implements Runnable {
    Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                clerk.get();
            } catch (InterruptedException e) {
            }
        }


    }
}
